#include "Stream.h"
#include "Logger.h"

NS_B2D_BEGIN



Stream::Stream(void)
	: mSize(0)
	, mIsOpen(false)
{
}

Stream::~Stream(void)
{
}

void Stream::open(AccessMode mode)
{
	// If open already, close first
	if(mIsOpen == true)
		close();
	openImpl(mode);

	mAccessMode = mode;
	mIsOpen = true;
}

void Stream::close(void)
{
	if(mIsOpen == true)
	{
		closeImpl();
		mIsOpen = false;
	}
}

size_t Stream::read(void* output, size_t size)
{
	// Check its ok to read
	if(mIsOpen != true || mAccessMode == AccessMode::WRITE)
	{
		B2D_LOG_ERROR("Could not read from stream \"%s\" due to %s"
			, mName.c_str()
			, (mIsOpen ? "the stream not being open." : "the stream being write-only."));
		return 0;
	}

	return readImpl(output, size);
}

size_t Stream::write(const void* input, size_t size)
{
	// Check its ok to write
	if(mIsOpen != true || mAccessMode == AccessMode::READ)
	{
		B2D_LOG_ERROR("Could not read from stream \"%s\" due to %s"
			, mName.c_str()
			, (mIsOpen ? "the stream not being open." : "the stream being read-only."));
		return 0;
	}

	return writeImpl(input, size);
}

size_t Stream::skip(size_t size)
{
	// Check its open
	if(mIsOpen == false)
	{
		B2D_LOG_ERROR("Could not skip stream \"%s\" as it isn't open", mName.c_str());
		return 0;
	}

	return skipImpl(size);
}

size_t Stream::seek(size_t offset)
{
	// Check its open
	if(mIsOpen == false)
	{
		B2D_LOG_ERROR("Could not seek stream \"%s\" as it isn't open", mName.c_str());
		return 0;
	}

	return seekImpl(offset);
}

bool Stream::isEOF(void) const
{
	return ( getPosition() >= mSize );
}


NS_B2D_END